#ifndef _VN_BUTTON_H_
#define _VN_BUTTON_H_

#include <functional>
#include "..\Math\Vector2.h"

class Button
{
public:
	class ICallback
	{
	public:
		virtual ~ICallback(void){}
		virtual void call() = 0; 
	};

	template <class T>
	class CallbackFunction : public ICallback
	{
	public:
		T* m_object;
		void(T::*m_method)();
		CallbackFunction(T* p_object, void(T::*p_method)()) : m_object(p_object), m_method(p_method){}
		void call() { (*m_object.*m_method)(); }
	};

	Button(void) : m_callbackFptr(nullptr), m_callback(nullptr) {}
	virtual ~Button(void)
	{
		if (m_callbackFptr != nullptr)
		{
			delete m_callbackFptr;
			m_callbackFptr = nullptr;
		}
	}

	virtual void update() = 0;
	virtual void setActive(bool p_value) = 0;
	virtual void setDoRender(bool p_value) = 0;

	const vn::Vector2& getPosition() { return m_position; };
	virtual void setPosition(const vn::Vector2& p_position) { m_position = p_position; }

	template <class T>
	void registerFunctionCallback(T* p_object, void (T::*p_method)())
	{
		if (m_callbackFptr == nullptr)
		{
			m_callbackFptr = new CallbackFunction<T>(p_object, p_method);
		}
		else
		{
			delete m_callbackFptr;
			m_callbackFptr = new CallbackFunction<T>(p_object, p_method);
		}
	}

	void registerFunctionCallback(std::function<void()> p_callback) { m_callback = p_callback; }

	void call()
	{
		if (m_callback != nullptr)
			m_callback();
		/*if (m_callbackFptr != nullptr)
		{
			m_callbackFptr->call();
		}*/
	}

protected:
	std::function<void()> m_callback;
	ICallback* m_callbackFptr;
	vn::Vector2 m_position;
};

#endif // _VN_BUTTON_H_